package be.destin.skos.core;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class FilesSource {

	/** log4j category */
	private static Logger log = Logger.getLogger(FilesSource.class);
	
	private static String unsplit(String[] source, String delimiter) {
		StringBuffer result = new StringBuffer();
		for (String line : source) {
			result.append(line);
			result.append(delimiter);
		}
		return result.toString();
	}
	
	private static void addDirectory(ConceptScheme aScheme, File directoryHandle, String[] rootNames, OurFileFilter fnf) {
		String[] fileNames = directoryHandle.list(fnf);
		if (fileNames != null && fileNames.length > 0) {
			for (String fileName: fileNames) {
				File fileHandle = new File(directoryHandle,fileName);
				if (fileHandle.isDirectory()) {
					String[] newRootNames = new String[rootNames.length+1];
					for (int i=0; i<rootNames.length; i++) {
						newRootNames[i] = rootNames[i];
					}
					newRootNames[rootNames.length] = fileName;
					addDirectory(aScheme,fileHandle,newRootNames,fnf);
				} else {
					int posExtension = fileName.indexOf('.'+fnf.getExtension());
					String currCode = unsplit(rootNames,"__")+fileName.substring(0,posExtension);
					Concept entry = aScheme.findAbout_Concept(currCode);
					if (entry== null) {
						entry = Concept.ensure(aScheme,currCode);
						entry = aScheme.putConcept(currCode, entry);
						entry.putPrefLabel(TermList.anyLanguage, null,
										fileName.substring(0,posExtension)
										+(rootNames.length > 0 ? (" ("+unsplit(rootNames,"/")+")") :""), null, null);
						Date aDate = new Date (fileHandle.lastModified());
						String currNote = aDate.toGMTString();
						entry.putScopeNote(TermList.anyLanguage,null,currNote, null);
						entry.putUrl(TermList.anyLanguage, fileHandle.getAbsolutePath());
					}
				}
			}
		}
		
	}

	protected static void load(ConceptScheme aScheme, Properties properties, String configFile, Map<String, String> notationsDefinitions) {
		String pattern = properties.getProperty("extension");
		if (pattern==null || pattern.isEmpty()) {
			log.error(aScheme.getAbout() + ": extension=extension-of-files-to-include is not specified.");			
		} else {
			String directory = properties.getProperty("directory");
			if (directory==null || directory.isEmpty()) {
				File configFileHandle = new File(configFile);
				directory = configFileHandle.getParent();
			}
			File directoryHandle = new File(directory);
			if (directoryHandle.isDirectory()) {
				OurFileFilter fnf = new OurFileFilter(pattern);
				addDirectory(aScheme, directoryHandle, new String[0], fnf);
			} else {
				log.error(aScheme.getAbout() + ": directory="+directory+" is not a real directory.");			
			}
		}
		if (Level.DEBUG.equals(log.getEffectiveLevel())) {
			StringBuffer result=new StringBuffer();
			for (Concept aConcept: aScheme.getConcept()) {
				result.append(aConcept.toString());
				result.append(" -- ");
			}
			log.debug(result.toString());
		}
	}

	private static class OurFileFilter implements FilenameFilter
	{

		String extension = "";

		OurFileFilter (String extension) {
			super();
			this.extension = extension;
		}

		public boolean accept ( File dir, String name )
		{
			if (extension == null || extension.isEmpty()) return true;
			if (name.endsWith( '.'+extension )) return true;
			if ( new File( dir, name ).isDirectory() ) return true;
			return false;
		}

		public String getExtension() {
			return extension;
		}

		public void setExtension(String extension) {
			this.extension = extension;
		}
	}
}
